package com.tarena.lbs.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.common.principle.UserPrinciple;
import com.tarena.lbs.common.utils.AuthenticationContextUtils;
import com.tarena.lbs.user.dao.mapper.UserMapper;
import com.tarena.lbs.user.dao.repository.UserRepository;
import com.tarena.lbs.user.pojo.param.UserParam;
import com.tarena.lbs.user.pojo.param.UserTagsParam;
import com.tarena.lbs.user.pojo.po.UserPO;
import com.tarena.lbs.user.pojo.po.UserTagsPO;
import com.tarena.lbs.user.pojo.vo.UserVO;
import com.tarena.lbs.user.service.UserService;
import com.tarena.lbs.user.utils.RandomUserName;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private UserMapper userMapper;

    @Override
    public void register(UserParam param) throws BusinessException {
        String phone = param.getPhone();
        Long count = userRepository.countUserByPhone(phone);
        Asserts.isTrue(count>0,new BusinessException("-2","手机号已经存在"));
        //2.封装数据
        UserPO poParam = assembleUserPO(param);
        //3.直接写入数据库
        userRepository.save(poParam);
    }

    @Override
    public UserVO detail() throws BusinessException {
        //1.解析jwt 拿到userPrinciple
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        Asserts.isTrue(userPrinciple==null,new BusinessException("-2","用户认证解析失败"));
        Integer userId = userPrinciple.getId();
        //2.仓储层查询唯一的po
        UserPO po = userRepository.getById(userId);
        Asserts.isTrue(po==null,new BusinessException("-2","用户信息不存在"));
        //3.转化vo
        UserVO vo=new UserVO();
        BeanUtils.copyProperties(po,vo);
        return vo;
    }

    private UserPO assembleUserPO(UserParam param) {
        UserPO po=new UserPO();
        BeanUtils.copyProperties(param,po);
        //补充必要数据 用户状态 0表示没有绑定标签 1 表示绑定了标签
        po.setStatus(0);
        //用户昵称 注册时候 不是用户填写的 为了快速注册 我们随机生成一个
        String randomName = RandomUserName.createRandomName();//老 大 小  张王李赵
        po.setNickName(randomName);
        po.setUserName(randomName);
        //注册时间
        po.setRegTime(new Date());
        return po;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void bindTag(UserTagsParam param) throws BusinessException {
        // 从认证上下文中获取当前用户ID，而不是依赖前端传递
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        if (userPrinciple == null) {
            log.warn("用户未登录，无法绑定标签");
            throw new BusinessException("-1", "用户未登录，无法绑定标签");
        }
        
        Integer userId = userPrinciple.getId();
        String tagIds = param.getTagIds();
        
        // 检查参数是否有效
        if (!StringUtils.hasText(tagIds)) {
            log.warn("绑定标签参数不完整: userId={}, tagIds={}", userId, tagIds);
            throw new BusinessException("-1", "请选择要绑定的标签");
        }
        
        // 先删除用户已有的标签关联
        userRepository.deleteUserTagsByUserId(userId);
        
        // 解析标签ID字符串，拆分为多个标签ID
        List<Integer> tagIdList = Arrays.stream(tagIds.split(","))
                .map(String::trim)
                .filter(StringUtils::hasText)
                .map(s -> {
                    try {
                        return Integer.parseInt(s);
                    } catch (NumberFormatException e) {
                        log.warn("无效的标签ID格式: {}", s);
                        return null;
                    }
                })
                .filter(s -> s != null)
                .collect(Collectors.toList());
        
        // 为每个标签ID创建关联记录
        for (Integer tagId : tagIdList) {
            UserTagsPO userTagsPO = new UserTagsPO();
            userTagsPO.setUserId(userId);
            userTagsPO.setTagId(tagId);
            // 写入数据库
            userRepository.add(userTagsPO);
        }
        
        // 更新用户状态为已绑定标签(1)
        UserPO userPO = userRepository.getById(userId);
        if (userPO != null) {
            userPO.setStatus(1);
            userMapper.updateById(userPO);
        }
    }

    // 小程序第三方登录相关
    @Override
    public UserPO findByOpenid(String providerType, String openid) {
        QueryWrapper<UserPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("union_id", openid);
        return userRepository.getOne(queryWrapper);
    }
    
    @Override
    public UserPO createWechatMiniUser(String openid) {
        UserPO userPO = new UserPO();
        // 设置默认值
        String randomName = RandomUserName.createRandomName();
        userPO.setUserName(randomName);
        userPO.setNickName(randomName);
        userPO.setUnionId(openid);
        userPO.setProviderType(1); // 1表示微信小程序
        userPO.setStatus(0); // 默认状态
        userPO.setRegTime(new Date());
        userRepository.save(userPO);
        return userPO;
    }
}
